package com.blackzs.controller;

import jakarta.annotation.Resource;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Model;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.HashMap;

@RestController
@RequestMapping("/flow")
public class FlowController {

    @Resource
    RepositoryService repositoryService;

    @Resource
    IdentityService identityService;

    @Resource
    RuntimeService runtimeService;

    @Resource
    TaskService taskService;

    /**
     * 启动一个流程
     *
     * @param modelId
     */
    @RequestMapping(value = "start/{modelId}")
    public void start(@PathVariable("modelId") String modelId) {
        Model modelData = repositoryService.getModel(modelId);
        ProcessInstance processInstance = null;
        try {
            // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
            identityService.setAuthenticatedUserId("admin");
            processInstance = runtimeService.startProcessInstanceByKey(modelData.getKey(), "myTestFlow1", new HashMap<String, Object>());
            String processInstanceId = processInstance.getId();
            System.out.println(processInstanceId);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
    }

    /**
     * 完成一个任务
     *
     * @param taskId
     */
    @RequestMapping(value = "complate/{taskId}")
    public void complate(@PathVariable("taskId") String taskId) {
        taskService.complete(taskId);
    }

    /**
     * 移动节点
     */
    @RequestMapping(value = "move/{proInstId}/{nodeId}/{toNodeId}")
    public void move(@PathVariable("proInstId") String proInstId,
                     @PathVariable("nodeId") String nodeId,
                     @PathVariable("toNodeId") String toNodeId) {
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(proInstId)
                .moveActivityIdTo(nodeId, toNodeId)
                .changeState();
    }

    /**
     * 移动流程实例
     */
    @RequestMapping(value = "moveExecution/{proInstId}/{toNodeId}")
    public void moveExecution(@PathVariable("proInstId") String proInstId,
                              @PathVariable("toNodeId") String toNodeId) {
        runtimeService.createChangeActivityStateBuilder()
                .moveExecutionToActivityId(proInstId, toNodeId)
                .changeState();
    }

    /**
     * 移动到父节点
     *
     * @param subProInstId
     * @param subNodeId
     * @param parentNodeId
     */
    @RequestMapping(value = "moveToParent/{subProInstId}/{subNodeId}/{parentNodeId}")
    public void moveToParent(@PathVariable("subProInstId") String subProInstId,
                             @PathVariable("subNodeId") String subNodeId,
                             @PathVariable("parentNodeId") String parentNodeId) {
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(subProInstId)
                .moveActivityIdToParentActivityId(subNodeId, parentNodeId)
                .changeState();
    }

    /**
     * 移动到子流程
     *
     * @param proInstId
     * @param subProcess
     * @param subNodeId
     * @param parentNodeId
     */
    @RequestMapping(value = "moveToSub/{proInstId}/{parentNodeId}/{subNodeId}/{subProcess}")
    public void moveToSub(@PathVariable("proInstId") String proInstId,
                          @PathVariable("subProcess") String subProcess,
                          @PathVariable("subNodeId") String subNodeId,
                          @PathVariable("parentNodeId") String parentNodeId) {
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(proInstId)
                .moveActivityIdToSubProcessInstanceActivityId(parentNodeId, subNodeId, subProcess)
                .changeState();
    }

    /**
     * 增加流程执行实例
     *
     * @param nodeId
     * @param proInstId
     * @param assigneeStr 以逗号隔开的字符串
     */
    @RequestMapping(value = "addExecution/{nodeId}/{proInstId}/{assignees}")
    public void addExecution(@PathVariable("nodeId") String nodeId,
                             @PathVariable("proInstId") String proInstId,
                             @PathVariable("assignees") String assigneeStr) {
        String[] assignees = assigneeStr.split(",");
        for (String assignee : assignees) {
            runtimeService.addMultiInstanceExecution(nodeId, proInstId, Collections.singletonMap("assignee", (Object) assignee));
        }
    }

    /**
     * 删除流程执行实例
     *
     * @param excutionId
     * @param complated  是否完成此流程执行实例
     */
    @RequestMapping(value = "delExecution/{excutionId}/{complated}")
    public void delExecution(@PathVariable("excutionId") String excutionId,
                             @PathVariable("complated") Boolean complated) {
        runtimeService.deleteMultiInstanceExecution(excutionId, complated);
    }

    @RequestMapping(value = "delInstance/{instId}")
    public void delInstance(@PathVariable("instId") String instId) {
        runtimeService.deleteProcessInstance(instId, "测试删除");
    }
}
